package com.tduck.cloud.form.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.amazonaws.partitions.PartitionRegionImpl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.tduck.cloud.account.entity.OrgEntity;
import com.tduck.cloud.account.entity.UserEntity;
import com.tduck.cloud.account.service.OrgService;
import com.tduck.cloud.account.service.RoleService;
import com.tduck.cloud.account.service.UserService;
import com.tduck.cloud.form.entity.RelationshipEntity;
import com.tduck.cloud.form.entity.UserFormEntity;
import com.tduck.cloud.form.entity.UserFormItemEntity;
import com.tduck.cloud.form.entity.enums.FormItemTypeEnum;
import com.tduck.cloud.form.entity.enums.FormTypeEnum;
import com.tduck.cloud.form.entity.struct.CheckboxSchemaStruct;
import com.tduck.cloud.form.entity.struct.InputResultStruct;
import com.tduck.cloud.form.mapper.UserFormItemMapper;
import com.tduck.cloud.form.service.RelationshipService;
import com.tduck.cloud.form.service.UserFormItemService;
import com.tduck.cloud.form.service.UserFormService;
import com.tduck.cloud.form.util.FormDataUtils;
import com.tduck.cloud.form.vo.FormFieldVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 表单表单项(FormItem)表服务实现类
 *
 * @author smalljop
 * @since 2020-11-19 10:49:18
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserFormItemServiceImpl extends ServiceImpl<UserFormItemMapper, UserFormItemEntity> implements UserFormItemService {


    private final UserFormService userFormService;
    private final UserService userService;
    private final RelationshipService relationshipService;
    private final OrgService orgService;
    private final RoleService roleService;
    private static final List<FormItemTypeEnum> MATRIX_ENUM = Lists.newArrayList(FormItemTypeEnum.MATRIX_INPUT, FormItemTypeEnum.MATRIX_SCALE, FormItemTypeEnum.MATRIX_SELECT);
    private static final String MATRIX_SELECT = "MATRIX_SELECT";

    @Override
    public List<UserFormItemEntity> listByFormKey(String key) {
        List<UserFormItemEntity> list = this.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, key));
        list.sort(Comparator.comparing(UserFormItemEntity::getSort));
        return list;
    }

    @Override
    public List<FormFieldVO> listFormFields(String formKey) {
        List<UserFormItemEntity> itemEntityList = this.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, formKey).eq(UserFormItemEntity::getDisplayType, 0));
        itemEntityList.sort(Comparator.comparing(UserFormItemEntity::getSort));

        // FormFieldVO 处理了部份组价默认显示label字段
        List<FormFieldVO> fields = itemEntityList.stream().map(FormFieldVO::new).collect(Collectors.toList());
        return fields;
    }

    @Override
    public List<FormFieldVO> listFormFields(String formKey, Long formUser) {
        UserFormEntity userFormEntity = userFormService.getByKey(formKey);
        List<UserFormItemEntity> itemEntityList = this.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, formKey).eq(UserFormItemEntity::getDisplayType, 0));
        itemEntityList.sort(Comparator.comparing(UserFormItemEntity::getSort));
        FormTypeEnum type = userFormEntity.getType();
        if (Objects.nonNull(type)) {
            if (type.equals(FormTypeEnum.ORG) || type.equals(FormTypeEnum.PERSON)) {
                // 动态组装rows
                itemEntityList = this.handleRelationship(itemEntityList, formUser, formKey);
            }
        }
        List<FormFieldVO> fields = itemEntityList.stream().map(FormFieldVO::new).collect(Collectors.toList());
        FormDataUtils.addFormDefaultDataField(userFormEntity, fields);
        return fields;
    }

    @Override
    public List<FormFieldVO> listAllFormFields(String formKey) {
        // 查询表单类型
        UserFormEntity userFormEntity = userFormService.getByKey(formKey);
        FormTypeEnum fromType = userFormEntity.getType();

        List<FormFieldVO> fields = this.listFormFields(formKey);
        FormDataUtils.addFormDefaultDataField(userFormEntity, fields);
        return fields;
    }

    @Override
    public Long getLastItemSort(String formKey) {
        Page<UserFormItemEntity> formItemEntityPage = baseMapper.selectPage(new Page<>(1, 1, false),
                Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, formKey)
                        .orderByDesc(UserFormItemEntity::getSort));
        // 去取第一个元素
        UserFormItemEntity first = CollUtil.getFirst(formItemEntityPage.getRecords());
        return ObjectUtil.isNull(first) ? 0 : first.getSort();
    }

    @Override
    public Boolean isSpecialTypeItem(UserFormItemEntity userFormItemEntity) {
        // 随机编号
        if (userFormItemEntity.getType() == FormItemTypeEnum.RANDOM_NUMBER) {
            return true;
        }
        // 不允许重复
        if (userFormItemEntity.getType() == FormItemTypeEnum.INPUT) {
            InputResultStruct builder = InputResultStruct.builder(userFormItemEntity.getScheme());
            return builder.isNotRepeat();
        }
        // 商品
        if (userFormItemEntity.getType() == FormItemTypeEnum.GOODS_SELECT) {
            return true;
        }
        // 预约时间
        if (userFormItemEntity.getType() == FormItemTypeEnum.RESERVE_DAY || userFormItemEntity.getType() == FormItemTypeEnum.RESERVE_TIME_RANGE) {
            return true;
        }
        // 投票
        if (userFormItemEntity.getType() == FormItemTypeEnum.CHECKBOX || userFormItemEntity.getType() == FormItemTypeEnum.RADIO || userFormItemEntity.getType() == FormItemTypeEnum.IMAGE_SELECT) {
            CheckboxSchemaStruct builder = CheckboxSchemaStruct.builder(userFormItemEntity.getScheme());
            // 单选多选带名额
            if (builder.getConfig().getOptions().stream().anyMatch(item -> ObjectUtil.isNotNull(item.getQuotaSetting()))) {
                return true;
            }
            return builder.getConfig().isShowVoteResult();
        }
        return false;
    }

    @Override
    public List<UserFormItemEntity> handleRelationship(List<UserFormItemEntity> formItemList, Long formUser, String formKey) {
        if (Objects.nonNull(formUser)) {
            log.info("formUser:{}", formUser);
            List<RelationshipEntity> relations = relationshipService.query().eq("evaluator", formUser).eq("form_key", formKey).list();
            if (CollUtil.isNotEmpty(relations)) {
                log.info("relations:{}", JSON.toJSONString(relations));
//                List<Long> evaluatedList = relations.stream().map(RelationshipEntity::getEvaluated).collect(Collectors.toList());
                for (UserFormItemEntity userFormItemEntity : formItemList) {
                    List<Long> evaluatedList = relations.stream().map(RelationshipEntity::getEvaluated).collect(Collectors.toList());
                    Integer relationShipType = relations.get(0).getType();
                    if (MATRIX_ENUM.contains(userFormItemEntity.getType())) {
                        // 处理匹配逻辑
                        Map<String, Object> scheme = userFormItemEntity.getScheme();
                        String typeId = (String) scheme.get("typeId");
                        JSONObject table = JSONUtil.parseObj(scheme.get("table"));
//                        log.info("table:{}", table);
                        //处理columns
                        if (typeId.equals(MATRIX_SELECT)) {
                            JSONArray columns = table.getJSONArray("columns");
                            for (int i = 0; i < columns.size(); i++) {
                                JSONObject column = columns.getJSONObject(i);
                                column.set("columnRadio", "");
                                column.set("columnInput", "");
                                column.set("visible", false);
                            }
                            log.debug("columns:{}", columns);
                            table.put("columns", columns);
                        }
                        if (FormItemTypeEnum.MATRIX_SCALE.equals(userFormItemEntity.getType())) {
                            JSONObject config = JSONUtil.parseObj(scheme.get("config"));
                            config.set("defaultValue", new JSONObject());
                            userFormItemEntity.setDefaultValue(JSON.toJSONString(new JSONObject()));
//                            log.debug("config:{}",config);
                            scheme.put("config", config);
                            List<Long> selectedList = (List<Long>) scheme.get("selectedList");
                            if (CollUtil.isNotEmpty(selectedList)) {
//                                log.debug("selectedList:{}", JSON.toJSONString(selectedList));
                                List<Long> userIds = roleService.getUserIdsByRoleIds(selectedList);
                                //找出该问题中匹配的角色用户id与当前问卷配置的被评价人的id的交集
                                evaluatedList = Lists.newArrayList(CollUtil.intersectionDistinct(userIds, evaluatedList));
//                                log.debug("containsUserIds:{}", evaluatedList);
                                if (CollUtil.isEmpty(evaluatedList)) {
                                    // 如果该用户配置的被评价人没有包含在该问题配置的角色中则隐藏该问题
                                    config.set("hideType", true);
                                    scheme.put("config", config);
                                    userFormItemEntity.setHideType(true);
                                    log.info("resultScheme:{}", JSON.toJSONString(scheme));
                                    continue;
                                }
                            }
                        }

                        JSONArray rows = table.getJSONArray("rows");
                        log.info("rows:{}", rows);
                        JSONArray resultRows = new JSONArray();
                        if (relationShipType.equals(FormTypeEnum.ORG.getValue())) {
                            List<OrgEntity> orgEntities = orgService.query().in("id", evaluatedList).list();
                            for (int i = 0; i < orgEntities.size(); i++) {
                                JSONObject row = new JSONObject();
                                OrgEntity orgEntity = orgEntities.get(i);
                                row.set("id", orgEntity.getId());
                                row.set("label", orgEntity.getName());
                                row.set("text", "");
                                row.set("colInput", "");
                                row.set("cols", table.getJSONArray("columns"));
                                resultRows.add(row);
                            }
                        }
                        if (relationShipType.equals(FormTypeEnum.PERSON.getValue())) {
                            List<UserEntity> userEntities = userService.query().in("id", evaluatedList).list();
                            for (int i = 0; i < userEntities.size(); i++) {
                                JSONObject row = new JSONObject();
                                UserEntity userEntity = userEntities.get(i);
                                row.set("id", userEntity.getId());
                                row.set("label", userEntity.getName());
                                row.set("text", "");
                                row.set("colInput", "");
                                row.set("cols", table.getJSONArray("columns"));
                                resultRows.add(row);
                            }
                        }
                        log.info("resultRows:{}", resultRows);
                        table.set("rows", resultRows);

                        scheme.put("table", table);
                        log.info("resultTable:{}", table);
                    }
                }
            }
        }
        return formItemList.stream().filter(f -> {
            Map<String, Object> scheme = f.getScheme();
            JSONObject config = JSONUtil.parseObj(scheme.get("config"));
            return !f.getHideType();
        }).collect(Collectors.toList());
    }


}
